/*******************************************************************************
 * Copyright (c) Jerges A. Bello G. 2014. Reservado todos los derechos.
 ******************************************************************************/
package com.jabex.core.bussines;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jabex.common.exceptions.ErrorFunctionalException;
import com.jabex.common.exceptions.ErrorOperationalException;
import com.jabex.common.exceptions.WarningFunctionalException;
import com.jabex.common.to.MessageTO;
import com.jabex.common.to.RolTO;
import com.jabex.common.to.SecurityTO;
import com.jabex.common.to.UserTO;
import com.jabex.common.util.Constants;
import com.jabex.persistence.dao.IUserDAO;
import com.jabex.persistence.model.Rol;
import com.jabex.persistence.model.Security;
import com.jabex.persistence.model.User;

/**
 * Created by Jerges Bello on 17/05/2014.
 */
@Service(value = IUserBp.SERVICE_NAME)
@Scope("request")
public class UserBp implements IUserBp {
	static private Logger logger = Logger.getLogger(UserBp.class);

	@Autowired
	@Qualifier(IUserDAO.MODEL_NAME)
	private IUserDAO userDao;


	@Override
	@Transactional
	public MessageTO insertUser(UserTO userTO) throws WarningFunctionalException, ErrorFunctionalException, ErrorOperationalException {
		MessageTO messageTO;
		try {
			User user = new User(userTO);
			Security security = new Security(userTO.getSecurity());
			user.setSecurity(security);
			messageTO = userDao.insertUser(user);
		} catch (WarningFunctionalException e) {
			logger.warn(e.getMessage());
			throw new WarningFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.INSERT.name(), null);
		} catch (ErrorFunctionalException e) {
			logger.error(e.getMessage());
			throw new ErrorFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.INSERT.name(), null);
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw new ErrorOperationalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), e.getLocalizedMessage(), Constants.TYPE_TRANSACTION.INSERT.name(), null);
		}
		return messageTO;
	}


	@Override
	@Transactional
	public MessageTO deleteUser(String id) throws WarningFunctionalException, ErrorFunctionalException, ErrorOperationalException {
		MessageTO messageTO;
		try {
			messageTO = userDao.deleteUser(id);
		} catch (WarningFunctionalException e) {
			logger.warn(e.getMessage());
			throw new WarningFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.DELETE.name(), null);
		} catch (ErrorFunctionalException e) {
			logger.error(e.getMessage());
			throw new ErrorFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.DELETE.name(), null);
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw new ErrorOperationalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), e.getLocalizedMessage(), Constants.TYPE_TRANSACTION.DELETE.name(), null);
		}
		return messageTO;
	}


	@Override
	@Transactional
	public MessageTO updateUser(UserTO userTO) throws WarningFunctionalException, ErrorFunctionalException, ErrorOperationalException {
		MessageTO messageTO;
		try {
			User user = new User(userTO);
			messageTO = userDao.updateUser(user);
		} catch (WarningFunctionalException e) {
			logger.warn(e.getMessage());
			throw new WarningFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.UPDATE.name(), null);
		} catch (ErrorFunctionalException e) {
			logger.error(e.getMessage());
			throw new ErrorFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.UPDATE.name(), null);
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw new ErrorOperationalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), e.getLocalizedMessage(), Constants.TYPE_TRANSACTION.UPDATE.name(), null);
		}
		return messageTO;

	}


	@Override
	@Transactional
	public UserTO getUserById(int id) throws WarningFunctionalException, ErrorFunctionalException, ErrorOperationalException {
		UserTO userTO = new UserTO();
		try {
			User user = userDao.getObjectById(String.valueOf(id));
			userTO.setName(user.getName());
			userTO.setLastName1(user.getLastName1());
			userTO.setLastName2(user.getLastName2());
			userTO.setDataBirth(LocalDate.parse(user.getDateBirth().toString()));
			userTO.setEmail(user.getEmail());
			userTO.setIsActive(user.getIsActive());
			SecurityTO securityTO = new SecurityTO();
			securityTO.setCodeApp(user.getSecurity().getCodeApp());
			securityTO.setNameApp(user.getSecurity().getNameApp());
			securityTO.setPassword(user.getSecurity().getPassword());
			userTO.setSecurity(securityTO);
		} catch (WarningFunctionalException e) {
			logger.warn(e.getMessage());
			throw new WarningFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.GET.name(), null);
		} catch (ErrorFunctionalException e) {
			logger.error(e.getMessage());
			throw new ErrorFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.GET.name(), null);
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw new ErrorOperationalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), e.getLocalizedMessage(), Constants.TYPE_TRANSACTION.GET.name(), null);
		}
		return userTO;
	}

	@Override
	@Transactional
	public List<UserTO> getAllUser() throws WarningFunctionalException, ErrorFunctionalException, ErrorOperationalException {
		List<UserTO> userTOList = new ArrayList<UserTO>();
		try {
			List<User> allUser = userDao.getAllUser();
			for (User user : allUser) {
				UserTO userTO = new UserTO();
                userTO.setCode(user.getId());
                userTO.setUserName(user.getUserName());
				userTO.setName(user.getName());
				userTO.setTypeDocument(user.getTypeDocument());
				userTO.setDocumentId(user.getDocumentId());
				userTO.setIsActive(user.getIsActive());
				userTO.setEmail(user.getEmail());
				userTO.setLastName1(user.getLastName1());
				if (user.getDateBirth() != null) {
					userTO.setDataBirth(LocalDate.parse(user.getDateBirth().toString()));
				}
				userTO.setLastName2(user.getLastName2());
				userTO.setSex(user.getSex());
				userTO.setTelephone(user.getTelephone());
				SecurityTO securityTO = new SecurityTO();
				if (user.getSecurity() != null) {
					securityTO.setCodeApp(user.getSecurity().getCodeApp());
					securityTO.setPassword(user.getSecurity().getPassword());
					securityTO.setNameApp(user.getSecurity().getNameApp());
					securityTO.setCreateDate(new LocalDate(user.getSecurity().getCreateDate()));
					securityTO.setCreateTime(new LocalDateTime(user.getSecurity().getCreateDate().getTime()));
				}
                List<RolTO> rolTOs = new ArrayList<RolTO>();
                for (Rol rol : user.getRolList()){
                    RolTO rolTO  = new RolTO();
                    rolTO.setDescription(rol.getDescription());
                    rolTO.setName(rol.getName());
                    rolTO.setType(rol.getType());
                    rolTO.setId(rol.getId());
                    rolTOs.add(rolTO);
                }
                userTO.setRolList(rolTOs);
				userTO.setSecurity(securityTO);
				userTOList.add(userTO);
			}

		} catch (WarningFunctionalException e) {
			logger.warn(e.getMessage());
			throw new WarningFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.GET.name(), null);
		} catch (ErrorFunctionalException e) {
			logger.error(e.getMessage());
			throw new ErrorFunctionalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), null, Constants.TYPE_TRANSACTION.GET.name(), null);
		} catch (Exception e) {
			logger.fatal(e.getMessage());
			throw new ErrorOperationalException(Constants.NAME_APP_MANAGER, Constants.CODE_APP_MANAGER, e.getMessage(),
					Constants.TYPE_ORIGIN.DESKTOP.name(), Constants.TYPE_CHANNELS.WEB.name(), e.getLocalizedMessage(), Constants.TYPE_TRANSACTION.GET.name(), null);
		}
		return userTOList;
	}
}
